home *** CD-ROM | disk | FTP | other *** search
/ BBS in a Box 15 / BBS in a box XV-2.iso / Files II / Prog / M / MacPerl 4.13 source.sit / Perl Source ƒ / MacPerl / MPHelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-27  |  6.6 KB  |  341 lines  |  [TEXT/MPS ]

  1. /*********************************************************************
  2. Project    :    MacPerl            -    Real Perl Application
  3. File        :    MPHelp.c            -    Various helpful functions
  4. Author    :    Matthias Neeracher
  5. Language    :    MPW C
  6.  
  7. $Log: MPHelp.c,v $
  8. Revision 1.1  1994/02/27  23:01:10  neeri
  9. Initial revision
  10.  
  11. Revision 0.2  1993/09/08  00:00:00  neeri
  12. Corrected some misunderstandings of dbm
  13.  
  14. Revision 0.1  1993/08/17  00:00:00  neeri
  15. Use Application directory
  16.  
  17. *********************************************************************/
  18.  
  19. #ifndef RUNTIME
  20.  
  21. #include "MPHelp.h"
  22. #include "MPConsole.h"
  23.  
  24. #include <Balloons.h>
  25. #include <ToolUtils.h>
  26. #include <TFileSpec.h>
  27. #include <ndbm.h>
  28. #include <ctype.h>
  29. #include <PLStringFuncs.h>
  30. #include <Folders.h>
  31. #include <fcntl.h>
  32. #include <ioctl.h>
  33. #include <stdio.h>
  34. #include <string.h>
  35.  
  36. #include "icemalloc.h"
  37.  
  38. static DBM *             OperatorBalloons = nil;
  39. static char                BalloonState = '?';
  40. static FSSpec            BalloonPath;
  41. static _mem_pool_ptr    HelpMem;
  42. static int                SavePoolID;
  43.  
  44. Boolean HasBalloons()
  45. {
  46.     CInfoPBRec    info;
  47.     
  48.     if (!HelpMem)
  49.         if (!(HelpMem = new_malloc_pool(4711, (16 * 1024))))
  50.             return false;
  51.             
  52.     SavePoolID = _default_mem_pool->id;
  53.     set_default_pool(4711);
  54.     
  55.     if (OperatorBalloons)
  56.         return true;
  57.         
  58.     switch (BalloonState) {
  59.     case '+':
  60.         if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
  61.             return true;
  62.     case '?':
  63.         BalloonState             = '+';
  64.         BalloonPath.vRefNum     = gAppVol;
  65.         BalloonPath.parID        = gAppDir;
  66.         PLstrcpy(BalloonPath.name, "\pMacPerl Help");
  67.         
  68.         if (!FSpCatInfo(&BalloonPath, &info)) 
  69.             if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
  70.                 return true;
  71.         
  72.         if (!FindFolder(
  73.                 kOnSystemDisk, 
  74.                 kPreferencesFolderType, 
  75.                 false, 
  76.                 &BalloonPath.vRefNum,
  77.                 &BalloonPath.parID)
  78.             && !FSpCatInfo(&BalloonPath, &info) 
  79.         )     
  80.             if (OperatorBalloons = dbm_open(FSp2FullPath(&BalloonPath), DBM_RDONLY, 0))
  81.                 return true;
  82.         
  83.         BalloonState = '-';
  84.     case '-':
  85.         set_default_pool(SavePoolID);
  86.         return false;
  87.     }
  88. }
  89.  
  90. void HideBalloons()
  91. {
  92.     dbm_close(OperatorBalloons);
  93.         
  94.     OperatorBalloons = nil;
  95.  
  96.     set_default_pool(SavePoolID);
  97. }
  98.  
  99. void DoHelp(WindowPtr win, DPtr doc, Point pt, Boolean inText)
  100. {
  101.     short                    index;
  102.     short                    last;
  103.     short                    length;
  104.     datum                    key;
  105.     datum                    data;
  106.     Ptr                    txt;
  107.     Rect                    r;
  108.     HMMessageRecord    help;
  109.     
  110.     if (!HMGetBalloons() || HMIsBalloon())
  111.         return;
  112.         
  113.     if (inText) {
  114.         index = TEGetOffset(pt, doc->theText);
  115.         length= (*doc->theText)->teLength;
  116.         
  117.         if (index <= 0 || index >= length)
  118.             return;
  119.  
  120.         txt    = *(*doc->theText)->hText;
  121.         
  122.         if (islower(txt[index])) {
  123.             for (last = index+1; last < (*doc->theText)->teLength; last++)
  124.                 if (islower(txt[last]))
  125.                     continue;
  126.                 else if (isalnum(txt[last]))
  127.                     return;
  128.                 else
  129.                     break;
  130.             
  131.             while (index-- > 0) 
  132.                 if (islower(txt[index]))
  133.                     continue;
  134.                 else if (isalnum(txt[index]))
  135.                     return;
  136.                 else
  137.                     break;
  138.             
  139.             ++index;
  140.         } else {
  141.             last = index+1;
  142.         }
  143.         
  144.         if (!HasBalloons())
  145.             return;
  146.  
  147.         HLock((*doc->theText)->hText);
  148.         key.dptr = *(*doc->theText)->hText + index;
  149.         key.dsize = last - index;
  150.         data = dbm_fetch(OperatorBalloons, key);
  151.         HUnlock((*doc->theText)->hText);
  152.         
  153.         HideBalloons();
  154.         
  155.         if (!data.dptr)
  156.             return;
  157.             
  158.         help.hmmHelpType = kHMStringItem;
  159.         help.u.hmmString[0] = data.dsize;
  160.         memcpy(&help.u.hmmString+1, data.dptr, data.dsize);
  161.  
  162.         LocalToGlobal(&pt);
  163.         *(Point *) &r.top = pt;
  164.         *(Point *) &r.bottom = pt;
  165.         InsetRect(&r, -5, -5);
  166.         
  167.         HMShowBalloon(&help, pt, &r, nil, 0, 0, kHMRegularWindow);
  168.     } else {
  169.         r = win->portRect;
  170.         
  171.         r.right = 30;
  172.         r.top   = r.bottom-15;
  173.     
  174.         if (PtInRect(pt, &r)) {
  175.             help.hmmHelpType = kHMStringItem;
  176.             
  177.             switch (doc->lastState) {
  178.             case stateDocument+stateRdWr:
  179.                 index = 1;
  180.                 break;
  181.             case stateDocument+stateRdOnly:
  182.                 index = 2;
  183.                 break;
  184.             case stateConsole+stateRdWr:
  185.                 index = 3;
  186.                 break;
  187.             case stateConsole+stateRdOnly:
  188.                 index = 4;
  189.                 break;
  190.             case stateConsole+stateBlocked:
  191.                 index = 5;
  192.                 break;
  193.             default:
  194.                 return;
  195.             }
  196.             GetIndString(help.u.hmmString, 256, index);
  197.             
  198.             LocalToGlobal((Point *) &r.top);
  199.             LocalToGlobal((Point *) &r.bottom);
  200.             LocalToGlobal(&pt);
  201.             
  202.             HMShowBalloon(&help, pt, &r, nil, 0, 0, kHMRegularWindow);
  203.         }
  204.     }
  205. }
  206.  
  207. typedef struct {
  208.     long    start;
  209.     long    end;
  210. } HelpOffsets;
  211.  
  212. void Explain(DPtr doc)
  213. {
  214.     datum         key;
  215.     datum         data;
  216.     FILE *        help;
  217.     HelpOffsets    offsets;
  218.     Handle        txt;
  219.     char *        text;
  220.     short            pos;
  221.     
  222.     if (!HasBalloons())
  223.         return;
  224.  
  225.     if (doc) {
  226.         TEHandle        te;
  227.         
  228.         te = doc->theText;
  229.             
  230.         if (pos = (*te)->selEnd - (*te)->selStart) {
  231.             HLock((*te)->hText);
  232.             PtrToHand(*(*te)->hText + (*te)->selStart - 1, &txt, pos + 2);
  233.             HUnlock((*te)->hText);
  234.         }
  235.     } else
  236.         pos = 0;
  237.     
  238.     if (!pos) {
  239.         pos = 12;
  240.         PtrToHand("xMacPerl…Help", &txt, pos + 2);
  241.     }
  242.     
  243.     (*txt)[0] = 0;
  244.     (*txt)[pos + 1] = 0;
  245.     
  246.     HLock(txt);
  247.     key.dptr = *txt;
  248.     key.dsize = pos + 1;
  249.     data = dbm_fetch(OperatorBalloons, key);
  250.     
  251.     if (!data.dptr) {
  252.         SysBeep(0);
  253.         
  254.         DisposeHandle(txt);
  255.         HideBalloons();
  256.         return;
  257.     }
  258.  
  259.     help = fopen("Dev:Console:Perl Help", "a");
  260.     
  261.     fprintf(help, "\n------------- %s ---------------\n\n", *txt+1);
  262.     
  263.     DisposeHandle(txt);
  264.     
  265.     memcpy(&offsets, data.dptr, sizeof(HelpOffsets));
  266.     txt        =    NewHandle(offsets.end - offsets.start + 1);
  267.     HLock(txt);
  268.     
  269.     lseek(OperatorBalloons->fd(OperatorBalloons), offsets.start, 0);
  270.     (*txt)[read(OperatorBalloons->fd(OperatorBalloons), *txt, offsets.end - offsets.start)] = 0;
  271.  
  272.     HideBalloons();
  273.     
  274.     for (pos = 0, text = *txt; *text; ) {
  275.         if (!pos && *text == 'æ') {
  276.             if (text[1] == 'C' && isspace(text[2])) {
  277.                 for (text += 3; isspace(*text); ++text);
  278.                 
  279.                 goto nextchar;
  280.             } else if (text[1] == 'K' && text[2] == 'L' && isspace(text[3])) { 
  281.                 for (text += 3; isspace(*text); ++text);
  282.                 
  283.                 for (pos = 0;;++text)
  284.                     switch (*text) {
  285.                     case 'æ':
  286.                         if (pos) {
  287.                             putc(*text, help);
  288.                             ++pos;
  289.                             break;
  290.                         } else {
  291.                             putc('\n', help);
  292.                             pos = 0;
  293.                         
  294.                             goto nextchar;
  295.                         }
  296.                     case 0:
  297.                         if (pos)
  298.                             putc('\n', help);
  299.                         putc('\n', help);
  300.                     
  301.                         goto nextchar;
  302.                     case '\n':
  303.                         if (text[1] == '\n' || !pos || pos >= 30) {
  304.                             putc('\n', help);
  305.                             pos = 0;
  306.                         } else
  307.                             while (pos < 30) {
  308.                                 putc(' ', help);
  309.                                 ++pos;
  310.                             }
  311.                         break;
  312.                     case ' ':
  313.                     case '\t':
  314.                         break;
  315.                     default:
  316.                         putc(*text, help);
  317.                         ++pos;
  318.                         break;
  319.                     }
  320.             } else if (text[1] == 'D' && text[2] == 'T' && isspace(text[3]))
  321.                 for (text += 3; *text; )
  322.                     if (*text++ == '\n') {
  323.                         pos = 0;
  324.                         
  325.                         goto nextchar;
  326.                     }
  327.         }
  328.         putc(*text, help);
  329.             
  330.         pos = (*text++ != '\n');
  331. nextchar:
  332.         ;
  333.     }
  334.     
  335.     ioctl(fileno(help), WIOSELECT, NULL);
  336.     
  337.     fclose(help);
  338.     DisposeHandle(txt);
  339. }    
  340.  
  341. #endif